<?php

namespace BWL\webshopBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use JMS\SecurityExtraBundle\Annotation\Secure;
use BWL\webshopBundle\Entity\Period;
use BWL\webshopBundle\Entity\Factor;
use BWL\webshopBundle\Entity\Item;

class AdminController extends Controller
{

  /**
   * @Secure(roles="ROLE_ADMIN")
   */
  public function partsListAction() {
    $em = $this->getDoctrine();
    $items = $em->getRepository('BWLwebshopBundle:Item')->findAll();

    if(!$items) {
      throw $this->createNotFoundException('No product found.');
    }
    return $this->render('BWLwebshopBundle:Admin:partsList.html.twig', array('items' => $items));
  }

  /**
   * @Secure(roles="ROLE_ADMIN")
   */
  public function specificPartsListAction($id) {
    $doctrine = $this->getDoctrine();
    $item = $doctrine->getRepository('BWLwebshopBundle:Item')->find($id);
    $productName = $item->getName();
    $partList = $this->getPartList($id, array(), 1);
    /*  usort($partList, function ($a, $b) {
        if($a['dispoGrade'] == $b['dispoGrade'])
          return 0;
        return ($a['dispoGrade'] < $b['dispoGrade']) ? -1 : 1;
      });*/

    return $this->render('BWLwebshopBundle:Admin:specificPartsList.html.twig', array('productName' => $productName, 'partList' => $partList));
  }


  /**
   * @Secure(roles="ROLE_ADMIN")
   */
  function getPartList($productId, $partList, $dispoGrade) {
    $doctrine = $this->getDoctrine();
    $inclosingItemIdList = $doctrine->getRepository('BWLwebshopBundle:ItemItem')->findby(array('whole_item' => $productId));

    foreach($inclosingItemIdList as $inclosingItemId) {
      $inclosingItem = $inclosingItemId->getPartItem();
      $partListEntry = array(
        'name' => $inclosingItem->getName(),
        'count' => $inclosingItemId->getCount(),
        'dispoGrade' => $dispoGrade
      );

      array_push($partList, $partListEntry);
      $partList = $this->getPartList($inclosingItem->getId(), $partList, $dispoGrade + 1);
    }

    return $partList;
  }


  /**
   * @Secure(roles="ROLE_ADMIN")
   */
  public function abcAnalysisAction() {
    $request = $this->getRequest();
    $period = new Period();
    $period->setFrom(new \DateTime('first day of last month'));
    $period->setTo(new \DateTime('now'));

    $form = $this->createFormBuilder($period)
      ->add('from', 'date', array('label' => 'Von', 'format' => 'dd.MM.yyyy'))
      ->add('to', 'date', array('label' => 'Bis', 'format' => 'dd.MM.yyyy'))
      ->getForm();

    if($request->getMethod() == 'POST') {
      $form->bind($request);
    }

    $products = $this->getSoldProductsInPeriod($period->getFrom(), $period->getTo());
    $products_sum = $products;
    usort($products_sum, function ($a, $b) {
      if($a['value'] == $b['value'])
        return 0;
      return ($a['value'] < $b['value']) ? 1 : -1;
    });

    $complete_sum = 0;
    foreach($products_sum as $product) {
      $complete_sum += $product['value'];
    }
    $percent_sum = 0;
    foreach($products_sum as $key => $product) {
      $products_sum[$key]['percent'] = $product['value'] / $complete_sum * 100;
      $percent_sum += $products_sum[$key]['percent'];
      $products_sum[$key]['class'] = ($percent_sum > 95 ? 'C' : ($percent_sum > 75 ? 'B' : 'A'));
    }


    return $this->render('BWLwebshopBundle:Admin:abcAnalysis.html.twig', array(
      'form' => $form->createView(),
      'products' => $products,
      'products_sum' => $products_sum
    ));
  }

  public function primaryRequirementsAction() {
    $request = $this->getRequest();
    $factor = new Factor();
    $factor->setFactor(0.2);
    $form = $this->createFormBuilder($factor)
      ->add('factor', 'percent', array('label' => 'Alpha', 'max_length' => 3))
      ->getForm();
    if($request->getMethod() == 'POST') {
      $form->bind($request);
    }
    $components = $this->getPrimaryRequirements($factor->getFactor());

    return $this->render('BWLwebshopBundle:Admin:primaryRequirements.html.twig',
      array(
        'form' => $form->createView(),
        'components' => $components));
  }

  function getPrimaryRequirements($alpha) {
    $primReq = $this->get('primaryrequirements');
    $requiredMonth = $this->getMonthToToday();
    $doctrine = $this->getDoctrine();
    $products = $doctrine->getRepository('BWLwebshopBundle:Item')->findAll();
    $components = array();
    foreach($products as $product) {
      $components[$product->getName()] = array();
      $avgSum = 0;
      $avgCount = 0;
      foreach($requiredMonth as $month) {
        if($month->format('m') - 1 < sizeof($requiredMonth)) {
          $requirement = $this->getRequirements(
            $product, new \DateTime('first day of' . $month->format('M')),
            new \DateTime('last day of' . $month->format('M')));
          if($month->format('m') < sizeof($requiredMonth)) {
            $components[$product->getName()][$month->format('M')]['requirement'] = $requirement[0][1];
            $avgSum += $requirement[0][1];
            $primReq->addForAvg($requirement[0][1]);
          } else {
            $components[$product->getName()][$month->format('M')]['requirement'] = '';
          }


          $components[$product->getName()][$month->format('M')]['average'] = $primReq->getAVG(); //$avgSum / $avgCount;
        } else {
          $components[$product->getName()][$month->format('M')]['requirement'] = '';
          $components[$product->getName()][$month->format('M')]['average'] = '';
        }
        if($month == new \DateTime('2012-01-01')) {
          $components[$product->getName()][$month->format('M')]['primaryRequirement'] = $requirement[0][1];
        } else {
          $monthBefore = new \DateTime('2012-' . (($month->format('m')) - 1) . '-01');
          $monthBefore = $monthBefore->format('M');
          $preRequirement = $components[$product->getName()][$monthBefore]['requirement'];
          $prePrimRequirement = $components[$product->getName()][$monthBefore]['primaryRequirement'];
          $components[$product->getName()][$month->format('M')]['primaryRequirement'] = $prePrimRequirement + ($alpha * ($preRequirement - $prePrimRequirement));
        }
      }

    }
    return $components;
  }


  function getRequirements(Item $product, \DateTime $from, \DateTime $to) {
    $qb = $this->getDoctrine()->getManager()->createQueryBuilder();


    $qb->select('SUM(o.count)');
    $qb->from('BWLwebshopBundle:Ordering', 'o');
    $qb->where('o.orderDate >= :from');
    $qb->andWhere('o.orderDate <= :to');
    $qb->andWhere('o.item = :item');
    $qb->setParameters(array(
      'from' => $from,
      'to' => $to,
      'item' => $product
    ));
    $qb->groupBy('o.item');
    return $qb->getQuery()->getResult();

  }


  function getMonthToToday() {
    $requiredMonth = array();
    $actualMonthCount = new\DateTime('now');
    $actualMonthCount = $actualMonthCount->format('m') + 1;
    while($actualMonthCount > 0) {
      $month = new\DateTime('-' . ($actualMonthCount - 2) . ' Month');
      $date = new \DateTime('2012-' . $month->format('m') . '-01');
      array_push($requiredMonth, $date);
      $actualMonthCount--;
    }
    return $requiredMonth;
  }


  function getSoldProductsInPeriod(\DateTime $from, \DateTime $to) {
    $to->modify('+1 day'); //sonst suchen wir nur bis 0:00 Uhr des angegebenen Tages
    $qb = $this->getDoctrine()->getManager()->createQueryBuilder();


    $qb->select(array('i.name AS name', 'SUM(i.basePrice * o.count) AS count'));
    $qb->from('BWLwebshopBundle:Item', 'i');
    $qb->leftJoin('i.orderings', 'o');
    $qb->where('o.orderDate >= :from');
    $qb->andWhere('o.orderDate <= :to');
    $qb->setParameters(array(
      'from' => $from,
      'to' => $to
    ));
    $qb->groupBy('i.name');
    $qb->orderBy('i.name', 'ASC');
    return $qb->getQuery()->getResult();
  }

  public function orderTrackingAction() {
    return $this->render('BWLwebshopBundle:Admin:orderTracking.html.twig');
  }

  public function orderTrackingRequirementsAction() {
    $em = $this->getDoctrine()->getManager();

    $from = new \DateTime('first day of this month');
    $from->setTime(0, 0);
    $to = new \DateTime('last day of this month');
    $to->setTime(0, 0);
    $form = $this->buildPeriodForm($from, $to);
    $data = $form->getData();

    // Updates all requirements
    $em->getRepository('BWLwebshopBundle:Requirement')->updateByOrderings();

    // Get current requirements
    $requirements = $em->getRepository('BWLwebshopBundle:Requirement')->findByPeriod($data->getFrom(), $data->getTo());
    return $this->render('BWLwebshopBundle:Admin:orderTrackingRequirements.html.twig', array(
      'form' => $form->createView(),
      'requirements' => $requirements
    ));
  }

  public function orderTrackingRequirementFulfilmentAction() {
    $em = $this->getDoctrine()->getManager();

    $from = new \DateTime('first day of this month');
    $from->setTime(0, 0);
    $to = new \DateTime('last day of this month');
    $to->setTime(0, 0);
    $form = $this->buildPeriodForm($from, $to);
    $data = $form->getData();

    // Updates all requirements
    $em->getRepository('BWLwebshopBundle:Requirement')->updateByOrderings();

    $fulfilments = $em->getRepository('BWLwebshopBundle:RequirementFulfilment')->findByPeriod($data->getFrom(), $data->getTo());
    return $this->render('BWLwebshopBundle:Admin:orderTrackingRequirementFulfilment.html.twig', array(
      'form' => $form->createView(),
      'fulfilments' => $fulfilments
    ));
  }


  public function orderTrackingRequirementDerivationAction(){
    $em = $this->getDoctrine()->getManager();

    $from = new \DateTime('first day of this month');
    $from->setTime(0, 0);
    $to = new \DateTime('last day of this month');
    $to->setTime(0, 0);
    $form = $this->buildPeriodForm($from, $to);
    $data = $form->getData();

    // Updates all requirements
    $em->getRepository('BWLwebshopBundle:Requirement')->updateByOrderings();

    $derivations = $em->getRepository('BWLwebshopBundle:RequirementDerivation')->findByPeriod($data->getFrom(), $data->getTo());
    return $this->render('BWLwebshopBundle:Admin:orderTrackingRequirementDerivation.html.twig', array(
      'form' => $form->createView(),
      'derivations' => $derivations
    ));
  }

  public function orderTrackingAssignmentsAction() {
    $em = $this->getDoctrine()->getManager();

    $from = new \DateTime('first day of this month');
    $to = new \DateTime();
    $from->setTime(0, 0);
    $to->setTime(0, 0);
    $form = $this->buildPeriodForm($from, $to);
    $data = $form->getData();

    // Updates all requirements
    $em->getRepository('BWLwebshopBundle:Requirement')->updateByOrderings();

    $assignments = $em->getRepository('BWLwebshopBundle:Assignment')->findByPeriod($data->getFrom(), $data->getTo());
    return $this->render('BWLwebshopBundle:Admin:orderTrackingAssignments.html.twig', array(
      'form' => $form->createView(),
      'assignments' => $assignments
    ));
  }


  /**
   * Builds the period form.
   * @return \Symfony\Component\Form\Form periodForm
   */
  private function buildPeriodForm(\DateTime $from, \DateTime $to) {
    $request = $this->getRequest();

    $period = new Period();
    $period->setFrom($from);
    $period->setTo($to);

    $form = $this->createFormBuilder($period)
      ->add('from', 'date', array('label' => 'Von:', 'format' => 'dd.MM.yyyy'))
      ->add('to', 'date', array('label' => 'Bis:', 'format' => 'dd.MM.yyyy'))
      ->getForm();

    if($request->getMethod() == 'POST') {
      $form->bind($request);
    }

    return $form;
  }

}
